﻿using System;
using System.Collections.Generic;
using System.Text;
using CodePlex.Resourceful.Amazon.S3;
using System.Text.RegularExpressions;

namespace CodePlex.Resourceful.Sun.CloudStorage
{
    public class SunCloudStorageConnection : S3Connection
    {

      

        public SunCloudStorageConnection(SunCloudStorageClient client)
            : base(client, RequestStyle.Path)
        {

        }

        protected override S3ConnectionOptions Options
        {
            get
            {
                S3ConnectionOptions rt = new S3ConnectionOptions();
                rt.SniffRedirects = false;
                return rt;
            }
        }


        public override ReadOnlyList<Key, string> ListBucket(string bucket)
        {
            return this.InternalListBucket(bucket).Keys;
        }

        public override ReadOnlyList<Key, string> ListBucket(string bucket, string prefix)
        {
            return new ReadOnlyList<Key, string>(this.InternalListBucket(bucket).Keys.FindAll(delegate(Key item)
            {
                return item.Name.StartsWith(prefix);
            }), delegate(Key item)
            {
                return item.Name;
            });
        }

        public override ListBucketResult ListBucket(string bucket, string prefix, string delimiter)
        {
            ListBucketResult results = this.InternalListBucket(bucket);


            List<Key> keys = new List<Key>();
            List<string> commonPrefixes = new List<string>();


            foreach(Key key in results.Keys)
            {
                if (!key.Name.StartsWith(prefix))
                    continue;

                string rest = key.Name.Substring(prefix.Length);

                int i = rest.IndexOf(delimiter);

                if (i == -1)
                {
                    keys.Add(key);
                }
                else
                {
                    string commonPrefix = prefix + rest.Substring(0, i) + delimiter;
                    if (!commonPrefixes.Contains(commonPrefix))
                    {
                        commonPrefixes.Add(commonPrefix);
                    }
                }
            }

            return new ListBucketResult(keys, commonPrefixes);
        }


        private ListBucketResult InternalListBucket(string bucket)
        {
            List<Key> keys = new List<Key>();
            List<string> commonPrefixes = new List<string>();


            InternalListBucketResult result = InternalListBucketCall(bucket, null, null, 0, null);

            keys.AddRange(result.Objects);
            commonPrefixes.AddRange(result.CommonPrefixes);

            return new ListBucketResult(keys, commonPrefixes);
        }



        public override BucketLoggingStatus GetLoggingStatus(string bucket)
        {
            return BucketLoggingStatus.Disabled;
        }



        private string GetGroup(string input, string pattern)
        {
            Match m = Regex.Match(input, pattern, RegexOptions.Singleline);
            if (m.Success)
            {
                return m.Groups[1].Value;
            }
            return null;
        }

        private void SafeGet(string body, string pattern, NameValuePairs fields, string key)
        {
            try
            {
                string value = GetGroup(body, pattern);
                if (value != null)
                    fields[key] = value;
            }
            catch (Exception ex) { }
        }
        protected override S3Exception Unexpected(ClientResponse response)
        {
            HttpStatus status = response.HttpStatus;

            string responseText = response.AsString();

            string body = GetGroup(responseText, "<body>(.*?)</body>");

            NameValuePairs fields = new NameValuePairs();

           
            if (body != null)
            {
                SafeGet(body, "<h1>(.*?)</h1>", fields, "H1");
                SafeGet(body, "<p><b>message</b>(.*?)</p>", fields, "Message");
                SafeGet(body, "<p><b>description</b>(.*?)</p>", fields, "Description");

            }


           

            fields.Add("Status", status.ToString());

            string message = Utils.SafeGet(fields, "Message");
            if (string.IsNullOrEmpty(message))
            {
                message = status.Description;
            }

            return S3Exception.Format(fields, null, message);
        }
       

    }
}
